<?php

// +----------------------------------------------------------------------

// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]

// +----------------------------------------------------------------------

// | Copyright (c) 2006-2013 http://thinkphp.cn All rights reserved.

// +----------------------------------------------------------------------

// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )

// +----------------------------------------------------------------------

// | Author: liu21st <liu21st@gmail.com>

// +----------------------------------------------------------------------



/**

 * Think API模式函数库

 */



/**

 * 抛出异常处理

 * @param string $msg 异常消息

 * @param integer $code 异常代码 默认为0

 * @return void

 */

function E($msg, $code=0) {

    throw new Think\Exception($msg, $code);

}



/**

 * 记录和统计时间（微秒）和内存使用情况

 * 使用方法:

 * <code>

 * G('begin'); // 记录开始标记位

 * // ... 区间运行代码

 * G('end'); // 记录结束标签位

 * echo G('begin','end',6); // 统计区间运行时间 精确到小数后6位

 * echo G('begin','end','m'); // 统计区间内存使用情况

 * 如果end标记位没有定义，则会自动以当前作为标记位

 * 其中统计内存使用需要 MEMORY_LIMIT_ON 常量为true才有效

 * </code>

 * @param string $start 开始标签

 * @param string $end 结束标签

 * @param integer|string $dec 小数位或者m

 * @return mixed

 */

function G($start,$end='',$dec=4) {

    static $_info       =   array();

    static $_mem        =   array();

    if(is_float($end)) { // 记录时间

        $_info[$start]  =   $end;

    }elseif(!empty($end)){ // 统计时间和内存使用

        if(!isset($_info[$end])) $_info[$end]       =  microtime(TRUE);

        if(MEMORY_LIMIT_ON && $dec=='m'){

            if(!isset($_mem[$end])) $_mem[$end]     =  memory_get_usage();

            return number_format(($_mem[$end]-$_mem[$start])/1024);

        }else{

            return number_format(($_info[$end]-$_info[$start]),$dec);

        }



    }else{ // 记录时间和内存使用

        $_info[$start]  =  microtime(TRUE);

        if(MEMORY_LIMIT_ON) $_mem[$start]           =  memory_get_usage();

    }

}



/**

 * 获取和设置语言定义(不区分大小写)

 * @param string|array $name 语言变量

 * @param string $value 语言值

 * @return mixed

 */

function L($name=null, $value=null) {

    static $_lang = array();

    // 空参数返回所有定义

    if (empty($name))

        return $_lang;

    // 判断语言获取(或设置)

    // 若不存在,直接返回全大写$name

    if (is_string($name)) {

        $name = strtoupper($name);

        if (is_null($value))

            return isset($_lang[$name]) ? $_lang[$name] : $name;

        $_lang[$name] = $value; // 语言定义

        return;

    }

    // 批量定义

    if (is_array($name))

        $_lang = array_merge($_lang, array_change_key_case($name, CASE_UPPER));

    return;

}



/**

 * 添加和获取页面Trace记录

 * @param string $value 变量

 * @param string $label 标签

 * @param string $level 日志级别

 * @param boolean $record 是否记录日志

 * @return void

 */

function trace($value='[think]',$label='',$level='DEBUG',$record=false) {

    return Think\Think::trace($value,$label,$level,$record);

}



/**

 * 编译文件

 * @param string $filename 文件名

 * @return string

 */

function compile($filename) {

    $content    =   php_strip_whitespace($filename);

    $content    =   trim(substr($content, 5));

    // 替换预编译指令

    $content    =   preg_replace('/\/\/\[RUNTIME\](.*?)\/\/\[\/RUNTIME\]/s', '', $content);

    if(0===strpos($content,'namespace')){

        $content    =   preg_replace('/namespace\s(.*?);/','namespace \\1{',$content,1);

    }else{

        $content    =   'namespace {'.$content;

    }

    if ('?>' == substr($content, -2))

        $content    = substr($content, 0, -2);

    return $content.'}';

}



/**

 * 获取输入参数 支持过滤和默认值

 * 使用方法:

 * <code>

 * I('id',0); 获取id参数 自动判断get或者post

 * I('post.name','','htmlspecialchars'); 获取$_POST['name']

 * I('get.'); 获取$_GET

 * </code>

 * @param string $name 变量的名称 支持指定类型

 * @param mixed $default 不存在的时候默认值

 * @param mixed $filter 参数过滤方法

 * @return mixed

 */

function I($name,$default='',$filter=null) {

    if(strpos($name,'.')) { // 指定参数来源

        list($method,$name) =   explode('.',$name,2);

    }else{ // 默认为自动判断

        $method =   'param';

    }

    switch(strtolower($method)) {

        case 'get'     :   $input =& $_GET;break;

        case 'post'    :   $input =& $_POST;break;

        case 'put'     :   parse_str(file_get_contents('php://input'), $input);break;

        case 'param'   :

            switch($_SERVER['REQUEST_METHOD']) {

                case 'POST':

                    $input  =  $_POST;

                    break;

                case 'PUT':

                    parse_str(file_get_contents('php://input'), $input);

                    break;

                default:

                    $input  =  $_GET;

            }

            break;

        case 'request' :   $input =& $_REQUEST;   break;

        case 'session' :   $input =& $_SESSION;   break;

        case 'cookie'  :   $input =& $_COOKIE;    break;

        case 'server'  :   $input =& $_SERVER;    break;

        case 'globals' :   $input =& $GLOBALS;    break;

        default:

            return NULL;

    }

    if(empty($name)) { // 获取全部变量

        $data       =   $input;

        array_walk_recursive($data,'filter_exp');

        $filters    =   isset($filter)?$filter:C('DEFAULT_FILTER');

        if($filters) {

            $filters    =   explode(',',$filters);

            foreach($filters as $filter){

                $data   =   array_map_recursive($filter,$data); // 参数过滤

            }

        }

    }elseif(isset($input[$name])) { // 取值操作

        $data       =   $input[$name];

        is_array($data) && array_walk_recursive($data,'filter_exp');

        $filters    =   isset($filter)?$filter:C('DEFAULT_FILTER');

        if($filters) {

            $filters    =   explode(',',$filters);

            foreach($filters as $filter){

                if(function_exists($filter)) {

                    $data   =   is_array($data)?array_map_recursive($filter,$data):$filter($data); // 参数过滤

                }else{

                    $data   =   filter_var($data,is_int($filter)?$filter:filter_id($filter));

                    if(false === $data) {

                        return   isset($default)?$default:NULL;

                    }

                }

            }

        }

    }else{ // 变量默认值

        $data       =    isset($default)?$default:NULL;

    }

    return $data;

}



function array_map_recursive($filter, $data) {

     $result = array();

     foreach ($data as $key => $val) {

         $result[$key] = is_array($val)

             ? array_map_recursive($filter, $val)

             : call_user_func($filter, $val);

     }

     return $result;

 }



/**

 * 设置和获取统计数据

 * 使用方法:

 * <code>

 * N('db',1); // 记录数据库操作次数

 * N('read',1); // 记录读取次数

 * echo N('db'); // 获取当前页面数据库的所有操作次数

 * echo N('read'); // 获取当前页面读取次数

 * </code>

 * @param string $key 标识位置

 * @param integer $step 步进值

 * @return mixed

 */

function N($key, $step=0,$save=false) {

    static $_num    = array();

    if (!isset($_num[$key])) {

        $_num[$key] = (false !== $save)? S('N_'.$key) :  0;

    }

    if (empty($step))

        return $_num[$key];

    else

        $_num[$key] = $_num[$key] + (int) $step;

    if(false !== $save){ // 保存结果

        S('N_'.$key,$_num[$key],$save);

    }

}



/**

 * 字符串命名风格转换

 * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格

 * @param string $name 字符串

 * @param integer $type 转换类型

 * @return string

 */

function parse_name($name, $type=0) {

    if ($type) {

        return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function($match){return strtoupper($match[1]);}, $name));

    } else {

        return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));

    }

}



/**

 * 优化的require_once

 * @param string $filename 文件地址

 * @return boolean

 */

function require_cache($filename) {

    static $_importFiles = array();

    if (!isset($_importFiles[$filename])) {

        if (file_exists_case($filename)) {

            require $filename;

            $_importFiles[$filename] = true;

        } else {

            $_importFiles[$filename] = false;

        }

    }

    return $_importFiles[$filename];

}



/**

 * 区分大小写的文件存在判断

 * @param string $filename 文件地址

 * @return boolean

 */

function file_exists_case($filename) {

    if (is_file($filename)) {

        if (IS_WIN && C('APP_FILE_CASE')) {

            if (basename(realpath($filename)) != basename($filename))

                return false;

        }

        return true;

    }

    return false;

}



/**

 * 导入所需的类库 同java的Import 本函数有缓存功能

 * @param string $class 类库命名空间字符串

 * @param string $baseUrl 起始路径

 * @param string $ext 导入的文件扩展名

 * @return boolean

 */

function import($class, $baseUrl = '', $ext=EXT) {

    static $_file = array();

    $class = str_replace(array('.', '#'), array('/', '.'), $class);

    if (isset($_file[$class . $baseUrl]))

        return true;

    else

        $_file[$class . $baseUrl] = true;

    $class_strut     = explode('/', $class);

    if (empty($baseUrl)) {

        if ('@' == $class_strut[0] || MODULE_NAME == $class_strut[0]) {

            //加载当前模块的类库

            $baseUrl = MODULE_PATH;

            $class   = substr_replace($class, '', 0, strlen($class_strut[0]) + 1);

        }elseif (in_array($class_strut[0],array('Think','Org','Behavior','Com','Vendor')) || is_dir(LIB_PATH.$class_strut[0])) {

            // 系统类库包和第三方类库包

            $baseUrl = LIB_PATH;

        }else { // 加载其他模块的类库

            $baseUrl = APP_PATH;

        }

    }

    if (substr($baseUrl, -1) != '/')

        $baseUrl    .= '/';

    $classfile       = $baseUrl . $class . $ext;

    if (!class_exists(basename($class),false)) {

        // 如果类不存在 则导入类库文件

        return require_cache($classfile);

    }

}



/**

 * 基于命名空间方式导入函数库

 * load('@.Util.Array')

 * @param string $name 函数库命名空间字符串

 * @param string $baseUrl 起始路径

 * @param string $ext 导入的文件扩展名

 * @return void

 */

function load($name, $baseUrl='', $ext='.php') {

    $name = str_replace(array('.', '#'), array('/', '.'), $name);

    if (empty($baseUrl)) {

        if (0 === strpos($name, '@/')) {//加载当前模块函数库

            $baseUrl    =   MODULE_PATH.'Common/';

            $name       =   substr($name, 2);

        } else { //加载其他模块函数库

            $array      =   explode('/', $name);

            $baseUrl    =   APP_PATH . array_shift($array).'/Common/';

            $name       =   implode('/',$array);

        }

    }

    if (substr($baseUrl, -1) != '/')

        $baseUrl       .= '/';

    require_cache($baseUrl . $name . $ext);

}



/**

 * 快速导入第三方框架类库 所有第三方框架的类库文件统一放到 系统的Vendor目录下面

 * @param string $class 类库

 * @param string $baseUrl 基础目录

 * @param string $ext 类库后缀

 * @return boolean

 */

function vendor($class, $baseUrl = '', $ext='.php') {

    if (empty($baseUrl))

        $baseUrl = VENDOR_PATH;

    return import($class, $baseUrl, $ext);

}



/**

 * D函数用于实例化模型类 格式 [资源://][模块/]模型

 * @param string $name 资源地址

 * @param string $layer 模型层名称

 * @return Model

 */

function D($name='',$layer='') {

    if(empty($name)) return new Think\Model;

    static $_model  =   array();

    $layer          =   $layer? $layer : C('DEFAULT_M_LAYER');

    if(isset($_model[$name.$layer]))

        return $_model[$name.$layer];

    $class          =   parse_res_name($name,$layer);

    if(class_exists($class)) {

        $model      =   new $class(basename($name));

    }elseif(false === strpos($name,'/')){

        // 自动加载公共模块下面的模型

        $class      =   '\\Common\\'.$layer.'\\'.$name.$layer;

        $model      =   class_exists($class)? new $class($name) : new Think\Model($name);

    }else {

        Think\Log::record('D方法实例化没找到模型类'.$class,Think\Log::NOTICE);

        $model      =   new Think\Model(basename($name));

    }

    $_model[$name.$layer]  =  $model;

    return $model;

}



/**

 * M函数用于实例化一个没有模型文件的Model

 * @param string $name Model名称 支持指定基础模型 例如 MongoModel:User

 * @param string $tablePrefix 表前缀

 * @param mixed $connection 数据库连接信息

 * @return Model

 */

function M($name='', $tablePrefix='',$connection='') {

    static $_model  = array();

    if(strpos($name,':')) {

        list($class,$name)    =  explode(':',$name);

    }else{

        $class      =   'Think\\Model';

    }

    $guid           =   (is_array($connection)?implode('',$connection):$connection).$tablePrefix . $name . '_' . $class;

    if (!isset($_model[$guid]))

        $_model[$guid] = new $class($name,$tablePrefix,$connection);

    return $_model[$guid];

}



/**

 * 解析资源地址并导入类库文件

 * 例如 module/controller addon://module/behavior

 * @param string $name 资源地址 格式：[扩展://][模块/]资源名

 * @param string $layer 分层名称

 * @return string

 */

function parse_res_name($name,$layer,$level=1){

    if(strpos($name,'://')) {// 指定扩展资源

        list($extend,$name)  =   explode('://',$name);

    }else{

        $extend  =   '';

    }

    if(strpos($name,'/') && substr_count($name, '/')>=$level){ // 指定模块

        list($module,$name) =  explode('/',$name,2);

    }else{

        $module =   MODULE_NAME;

    }

    $array  =   explode('/',$name);

    $class  =   $module.'\\'.$layer;

    foreach($array as $name){

        $class  .=   '\\'.parse_name($name, 1);

    }

    // 导入资源类库

    if($extend){ // 扩展资源

        $class      =   $extend.'\\'.$class;

    }

    return $class.$layer;

}



/**

 * A函数用于实例化控制器 格式：[资源://][模块/]控制器

 * @param string $name 资源地址

 * @param string $layer 控制层名称

 * @param integer $level 控制器层次

 * @return Controller|false

 */

function A($name,$layer='',$level='') {

    static $_action = array();

    $layer  =   $layer? $layer : C('DEFAULT_C_LAYER');

    $level  =   $level? $level : ($layer == C('DEFAULT_C_LAYER')?C('CONTROLLER_LEVEL'):1);

    if(isset($_action[$name.$layer]))

        return $_action[$name.$layer];

    $class  =   parse_res_name($name,$layer,$level);

    if(class_exists($class)) {

        $action             =   new $class();

        $_action[$name.$layer]     =   $action;

        return $action;

    }else {

        return false;

    }

}



/**

 * 远程调用控制器的操作方法 URL 参数格式 [资源://][模块/]控制器/操作

 * @param string $url 调用地址

 * @param string|array $vars 调用参数 支持字符串和数组

 * @param string $layer 要调用的控制层名称

 * @return mixed

 */

function R($url,$vars=array(),$layer='') {

    $info   =   pathinfo($url);

    $action =   $info['basename'];

    $module =   $info['dirname'];

    $class  =   A($module,$layer);

    if($class){

        if(is_string($vars)) {

            parse_str($vars,$vars);

        }

        return call_user_func_array(array(&$class,$action.C('ACTION_SUFFIX')),$vars);

    }else{

        return false;

    }

}



/**

 * 执行某个行为

 * @param string $name 行为名称

 * @param Mixed $params 传入的参数

 * @return void

 */

function B($name, &$params=NULL) {

    if(strpos($name,'/')){

        list($name,$tag) = explode('/',$name);

    }else{

        $tag     =   'run';

    }

    return \Think\Hook::exec($name,$tag,$params);

}



/**

 * 去除代码中的空白和注释

 * @param string $content 代码内容

 * @return string

 */

function strip_whitespace($content) {

    $stripStr   = '';

    //分析php源码

    $tokens     = token_get_all($content);

    $last_space = false;

    for ($i = 0, $j = count($tokens); $i < $j; $i++) {

        if (is_string($tokens[$i])) {

            $last_space = false;

            $stripStr  .= $tokens[$i];

        } else {

            switch ($tokens[$i][0]) {

                //过滤各种PHP注释

                case T_COMMENT:

                case T_DOC_COMMENT:

                    break;

                //过滤空格

                case T_WHITESPACE:

                    if (!$last_space) {

                        $stripStr  .= ' ';

                        $last_space = true;

                    }

                    break;

                case T_START_HEREDOC:

                    $stripStr .= "<<<THINK\n";

                    break;

                case T_END_HEREDOC:

                    $stripStr .= "THINK;\n";

                    for($k = $i+1; $k < $j; $k++) {

                        if(is_string($tokens[$k]) && $tokens[$k] == ';') {

                            $i = $k;

                            break;

                        } else if($tokens[$k][0] == T_CLOSE_TAG) {

                            break;

                        }

                    }

                    break;

                default:

                    $last_space = false;

                    $stripStr  .= $tokens[$i][1];

            }

        }

    }

    return $stripStr;

}



/**

 * 浏览器友好的变量输出

 * @param mixed $var 变量

 * @param boolean $echo 是否输出 默认为True 如果为false 则返回输出字符串

 * @param string $label 标签 默认为空

 * @param boolean $strict 是否严谨 默认为true

 * @return void|string

 */

function dump($var, $echo=true, $label=null, $strict=true) {

    $label = ($label === null) ? '' : rtrim($label) . ' ';

    if (!$strict) {

        if (ini_get('html_errors')) {

            $output = print_r($var, true);

            $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';

        } else {

            $output = $label . print_r($var, true);

        }

    } else {

        ob_start();

        var_dump($var);

        $output = ob_get_clean();

        if (!extension_loaded('xdebug')) {

            $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);

            $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';

        }

    }

    if ($echo) {

        echo($output);

        return null;

    }else

        return $output;

}



/**

 * URL重定向

 * @param string $url 重定向的URL地址

 * @param integer $time 重定向的等待时间（秒）

 * @param string $msg 重定向前的提示信息

 * @return void

 */

function redirect($url, $time=0, $msg='') {

    //多行URL地址支持

    $url        = str_replace(array("\n", "\r"), '', $url);

    if (empty($msg))

        $msg    = "系统将在{$time}秒之后自动跳转到{$url}！";

    if (!headers_sent()) {

        // redirect

        if (0 === $time) {

            header('Location: ' . $url);

        } else {

            header("refresh:{$time};url={$url}");

            echo($msg);

        }

        exit();

    } else {

        $str    = "<meta http-equiv='Refresh' content='{$time};URL={$url}'>";

        if ($time != 0)

            $str .= $msg;

        exit($str);

    }

}



/**

 * 缓存管理

 * @param mixed $name 缓存名称，如果为数组表示进行缓存设置

 * @param mixed $value 缓存值

 * @param mixed $options 缓存参数

 * @return mixed

 */

function S($name,$value='',$options=null) {

    static $cache   =   '';

    if(is_array($options) && empty($cache)){

        // 缓存操作的同时初始化

        $type       =   isset($options['type'])?$options['type']:'';

        $cache      =   Think\Cache::getInstance($type,$options);

    }elseif(is_array($name)) { // 缓存初始化

        $type       =   isset($name['type'])?$name['type']:'';

        $cache      =   Think\Cache::getInstance($type,$name);

        return $cache;

    }elseif(empty($cache)) { // 自动初始化

        $cache      =   Think\Cache::getInstance();

    }

    if(''=== $value){ // 获取缓存

        return $cache->get($name);

    }elseif(is_null($value)) { // 删除缓存

        return $cache->rm($name);

    }else { // 缓存数据

        if(is_array($options)) {

            $expire     =   isset($options['expire'])?$options['expire']:NULL;

        }else{

            $expire     =   is_numeric($options)?$options:NULL;

        }

        return $cache->set($name, $value, $expire);

    }

}



/**

 * 快速文件数据读取和保存 针对简单类型数据 字符串、数组

 * @param string $name 缓存名称

 * @param mixed $value 缓存值

 * @param string $path 缓存路径

 * @return mixed

 */

function F($name, $value='', $path=DATA_PATH) {

    static $_cache  =   array();

    $filename       =   $path . $name . '.php';

    if ('' !== $value) {

        if (is_null($value)) {

            // 删除缓存

            if(false !== strpos($name,'*')){

                return false; // TODO 

            }else{

                unset($_cache[$name]);

                return Think\Storage::unlink($filename,'F');

            }

        } else {

            Think\Storage::put($filename,serialize($value),'F');

            // 缓存数据

            $_cache[$name]  =   $value;

            return ;

        }

    }

    // 获取缓存数据

    if (isset($_cache[$name]))

        return $_cache[$name];

    if (Think\Storage::has($filename,'F')){

        $value      =   unserialize(Think\Storage::read($filename,'F'));

        $_cache[$name]  =   $value;

    } else {

        $value          =   false;

    }

    return $value;

}



/**

 * 根据PHP各种类型变量生成唯一标识号

 * @param mixed $mix 变量

 * @return string

 */

function to_guid_string($mix) {

    if (is_object($mix)) {

        return spl_object_hash($mix);

    } elseif (is_resource($mix)) {

        $mix = get_resource_type($mix) . strval($mix);

    } else {

        $mix = serialize($mix);

    }

    return md5($mix);

}



/**

 * XML编码

 * @param mixed $data 数据

 * @param string $root 根节点名

 * @param string $item 数字索引的子节点名

 * @param string $attr 根节点属性

 * @param string $id   数字索引子节点key转换的属性名

 * @param string $encoding 数据编码

 * @return string

 */

function xml_encode($data, $root='think', $item='item', $attr='', $id='id', $encoding='utf-8') {

    if(is_array($attr)){

        $_attr = array();

        foreach ($attr as $key => $value) {

            $_attr[] = "{$key}=\"{$value}\"";

        }

        $attr = implode(' ', $_attr);

    }

    $attr   = trim($attr);

    $attr   = empty($attr) ? '' : " {$attr}";

    $xml    = "<?xml version=\"1.0\" encoding=\"{$encoding}\"?>";

    $xml   .= "<{$root}{$attr}>";

    $xml   .= data_to_xml($data, $item, $id);

    $xml   .= "</{$root}>";

    return $xml;

}



/**

 * 数据XML编码

 * @param mixed  $data 数据

 * @param string $item 数字索引时的节点名称

 * @param string $id   数字索引key转换为的属性名

 * @return string

 */

function data_to_xml($data, $item='item', $id='id') {

    $xml = $attr = '';

    foreach ($data as $key => $val) {

        if(is_numeric($key)){

            $id && $attr = " {$id}=\"{$key}\"";

            $key  = $item;

        }

        $xml    .=  "<{$key}{$attr}>";

        $xml    .=  (is_array($val) || is_object($val)) ? data_to_xml($val, $item, $id) : $val;

        $xml    .=  "</{$key}>";

    }

    return $xml;

}



/**

 * session管理函数

 * @param string|array $name session名称 如果为数组则表示进行session设置

 * @param mixed $value session值

 * @return mixed

 */

function session($name,$value='') {

    $prefix   =  C('SESSION_PREFIX');

    if(is_array($name)) { // session初始化 在session_start 之前调用

        if(isset($name['prefix'])) C('SESSION_PREFIX',$name['prefix']);

        if(C('VAR_SESSION_ID') && isset($_REQUEST[C('VAR_SESSION_ID')])){

            session_id($_REQUEST[C('VAR_SESSION_ID')]);

        }elseif(isset($name['id'])) {

            session_id($name['id']);

        }

        if('common' != APP_MODE){ // 其它模式可能不支持

            ini_set('session.auto_start', 0);

        }

        if(isset($name['name']))            session_name($name['name']);

        if(isset($name['path']))            session_save_path($name['path']);

        if(isset($name['domain']))          ini_set('session.cookie_domain', $name['domain']);

        if(isset($name['expire']))          ini_set('session.gc_maxlifetime', $name['expire']);

        if(isset($name['use_trans_sid']))   ini_set('session.use_trans_sid', $name['use_trans_sid']?1:0);

        if(isset($name['use_cookies']))     ini_set('session.use_cookies', $name['use_cookies']?1:0);

        if(isset($name['cache_limiter']))   session_cache_limiter($name['cache_limiter']);

        if(isset($name['cache_expire']))    session_cache_expire($name['cache_expire']);

        if(isset($name['type']))            C('SESSION_TYPE',$name['type']);

        if(C('SESSION_TYPE')) { // 读取session驱动

            $type   =   C('SESSION_TYPE');

            $class  =   strpos($type,'\\')? $type : 'Think\\Session\\Driver\\'. ucwords(strtolower($type));

            $hander =   new $class();

            session_set_save_handler(

                array(&$hander,"open"), 

                array(&$hander,"close"), 

                array(&$hander,"read"), 

                array(&$hander,"write"), 

                array(&$hander,"destroy"), 

                array(&$hander,"gc")); 

        }

        // 启动session

        if(C('SESSION_AUTO_START'))  session_start();

    }elseif('' === $value){ 

        if(0===strpos($name,'[')) { // session 操作

            if('[pause]'==$name){ // 暂停session

                session_write_close();

            }elseif('[start]'==$name){ // 启动session

                session_start();

            }elseif('[destroy]'==$name){ // 销毁session

                $_SESSION =  array();

                session_unset();

                session_destroy();

            }elseif('[regenerate]'==$name){ // 重新生成id

                session_regenerate_id();

            }

        }elseif(0===strpos($name,'?')){ // 检查session

            $name   =  substr($name,1);

            if(strpos($name,'.')){ // 支持数组

                list($name1,$name2) =   explode('.',$name);

                return $prefix?isset($_SESSION[$prefix][$name1][$name2]):isset($_SESSION[$name1][$name2]);

            }else{

                return $prefix?isset($_SESSION[$prefix][$name]):isset($_SESSION[$name]);

            }

        }elseif(is_null($name)){ // 清空session

            if($prefix) {

                unset($_SESSION[$prefix]);

            }else{

                $_SESSION = array();

            }

        }elseif($prefix){ // 获取session

            if(strpos($name,'.')){

                list($name1,$name2) =   explode('.',$name);

                return isset($_SESSION[$prefix][$name1][$name2])?$_SESSION[$prefix][$name1][$name2]:null;  

            }else{

                return isset($_SESSION[$prefix][$name])?$_SESSION[$prefix][$name]:null;                

            }            

        }else{

            if(strpos($name,'.')){

                list($name1,$name2) =   explode('.',$name);

                return isset($_SESSION[$name1][$name2])?$_SESSION[$name1][$name2]:null;  

            }else{

                return isset($_SESSION[$name])?$_SESSION[$name]:null;

            }            

        }

    }elseif(is_null($value)){ // 删除session

        if($prefix){

            unset($_SESSION[$prefix][$name]);

        }else{

            unset($_SESSION[$name]);

        }

    }else{ // 设置session

        if($prefix){

            if (!is_array($_SESSION[$prefix])) {

                $_SESSION[$prefix] = array();

            }

            $_SESSION[$prefix][$name]   =  $value;

        }else{

            $_SESSION[$name]  =  $value;

        }

    }

}



/**

 * Cookie 设置、获取、删除

 * @param string $name cookie名称

 * @param mixed $value cookie值

 * @param mixed $options cookie参数

 * @return mixed

 */

function cookie($name, $value='', $option=null) {

    // 默认设置

    $config = array(

        'prefix'    =>  C('COOKIE_PREFIX'), // cookie 名称前缀

        'expire'    =>  C('COOKIE_EXPIRE'), // cookie 保存时间

        'path'      =>  C('COOKIE_PATH'), // cookie 保存路径

        'domain'    =>  C('COOKIE_DOMAIN'), // cookie 有效域名

    );

    // 参数设置(会覆盖黙认设置)

    if (!is_null($option)) {

        if (is_numeric($option))

            $option = array('expire' => $option);

        elseif (is_string($option))

            parse_str($option, $option);

        $config     = array_merge($config, array_change_key_case($option));

    }

    // 清除指定前缀的所有cookie

    if (is_null($name)) {

        if (empty($_COOKIE))

            return;

        // 要删除的cookie前缀，不指定则删除config设置的指定前缀

        $prefix = empty($value) ? $config['prefix'] : $value;

        if (!empty($prefix)) {// 如果前缀为空字符串将不作处理直接返回

            foreach ($_COOKIE as $key => $val) {

                if (0 === stripos($key, $prefix)) {

                    setcookie($key, '', time() - 3600, $config['path'], $config['domain']);

                    unset($_COOKIE[$key]);

                }

            }

        }

        return;

    }

    $name = $config['prefix'] . $name;

    if ('' === $value) {

        if(isset($_COOKIE[$name])){

            $value =    $_COOKIE[$name];

            if(0===strpos($value,'think:')){

                $value  =   substr($value,6);

                return array_map('urldecode',json_decode(MAGIC_QUOTES_GPC?stripslashes($value):$value,true));

            }else{

                return $value;

            }

        }else{

            return null;

        }

    } else {

        if (is_null($value)) {

            setcookie($name, '', time() - 3600, $config['path'], $config['domain']);

            unset($_COOKIE[$name]); // 删除指定cookie

        } else {

            // 设置cookie

            if(is_array($value)){

                $value  = 'think:'.json_encode(array_map('urlencode',$value));

            }

            $expire = !empty($config['expire']) ? time() + intval($config['expire']) : 0;

            setcookie($name, $value, $expire, $config['path'], $config['domain']);

            $_COOKIE[$name] = $value;

        }

    }

}



/**

 * 加载动态扩展文件

 * @return void

 */

function load_ext_file($path) {

    // 加载自定义外部文件

    if(C('LOAD_EXT_FILE')) {

        $files      =  explode(',',C('LOAD_EXT_FILE'));

        foreach ($files as $file){

            $file   = $path.'Common/'.$file.'.php';

            if(is_file($file)) include $file;

        }

    }

    // 加载自定义的动态配置文件

    if(C('LOAD_EXT_CONFIG')) {

        $configs    =  C('LOAD_EXT_CONFIG');

        if(is_string($configs)) $configs =  explode(',',$configs);

        foreach ($configs as $key=>$config){

            $file   = $path.'Conf/'.$config.'.php';

            if(is_file($file)) {

                is_numeric($key)?C(include $file):C($key,include $file);

            }

        }

    }

}



/**

 * 获取客户端IP地址

 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字

 * @return mixed

 */

function get_client_ip($type = 0) {

    $type       =  $type ? 1 : 0;

    static $ip  =   NULL;

    if ($ip !== NULL) return $ip[$type];

    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {

        $arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);

        $pos    =   array_search('unknown',$arr);

        if(false !== $pos) unset($arr[$pos]);

        $ip     =   trim($arr[0]);

    }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {

        $ip     =   $_SERVER['HTTP_CLIENT_IP'];

    }elseif (isset($_SERVER['REMOTE_ADDR'])) {

        $ip     =   $_SERVER['REMOTE_ADDR'];

    }

    // IP地址合法验证

    $long = sprintf("%u",ip2long($ip));

    $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);

    return $ip[$type];

}



/**

 * 发送HTTP状态

 * @param integer $code 状态码

 * @return void

 */

function send_http_status($code) {

    static $_status = array(

        // Success 2xx

        200 => 'OK',

        // Redirection 3xx

        301 => 'Moved Permanently',

        302 => 'Moved Temporarily ',  // 1.1

        // Client Error 4xx

        400 => 'Bad Request',

        403 => 'Forbidden',

        404 => 'Not Found',

        // Server Error 5xx

        500 => 'Internal Server Error',

        503 => 'Service Unavailable',

    );

    if(isset($_status[$code])) {

        header('HTTP/1.1 '.$code.' '.$_status[$code]);

        // 确保FastCGI模式下正常

        header('Status:'.$code.' '.$_status[$code]);

    }

}



// 过滤表单中的表达式

function filter_exp(&$value){

    if (in_array(strtolower($value),array('exp','or'))){

        $value .= ' ';

    }

}



// 不区分大小写的in_array实现

function in_array_case($value,$array){

    return in_array(strtolower($value),array_map('strtolower',$array));

}

